//
//  AspectProxy.m
//  精通Objective-C
//
//  Created by 花强 on 2017/12/21.
//  Copyright © 2017年 花强. All rights reserved.
//

#import "AspectProxy.h"

@implementation AspectProxy
-(id)initWithObject:(id)object andInvoker:(id<Invoker>)invoker{
    return [self initWithObject:object selectors:@[] andInvoker:invoker];
}
-(id)initWithObject:(id)object selectors:(NSArray *)selectors andInvoker:(id<Invoker>)invoker{
    _proxyTarget = object;
    _invoker = invoker;
    _selectors = [selectors mutableCopy];
    return self;
}
-(void)registerSelector:(SEL)selector{
    NSValue * selValue = [NSValue valueWithPointer:selector];
    [self.selectors addObject:selValue];
}
//该方法会为目标对象中被调用的方法返回一个NSMethodSignature实例
//运行时系统要求在执行标准转发时实现这个方法
-(NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
    return [self.proxyTarget methodSignatureForSelector:sel];
}
-(void)forwardInvocation:(NSInvocation *)invocation{
    //调用目标方法前的横切功能；
    if ([self.invoker respondsToSelector:@selector(preInvoke:withTarget:)]) {
        if (self.selectors != nil) {
            SEL methodSel = [invocation selector];
            for (NSValue * selValue in self.selectors) {
                if (methodSel == [selValue pointerValue]) {
                    [[self invoker] preInvoke:invocation withTarget:self.proxyTarget];
                    break;
                }
            }
        }else{
//            [[self invoker] preInvoke:invocation withTarget:self.proxyTarget];
        }
    }
    //调用目标方法
    [invocation invokeWithTarget:self.proxyTarget];//invocation 文件提取
    //在调用目标方法之后执行横切操作；
    if ([self.invoker respondsToSelector:@selector(preInvoke:withTarget:)]) {
        if (self.selectors != nil) {
            SEL methodSel = [invocation selector];
            for (NSValue * selValue in self.selectors) {
                if (methodSel == [selValue pointerValue]) {
                    [[self invoker] postInvoke:invocation withTarget:self.proxyTarget];
                    break;
                }
            }
        }else{
//            [[self invoker] postInvoke:invocation withTarget:self.proxyTarget];
        }
    }
    
}
@end
